from functools import wraps

from django.forms import formset_factory, BaseFormSet
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q, Sum, Avg, Max, Min
from django.http import JsonResponse, HttpResponseForbidden, HttpResponseNotAllowed, Http404
from django.urls import reverse
from django.utils import timezone

from users.models import Student
from .models import ExamRecord, Subject, Exam, ScoreLossDetail
from .forms import ExamRecordForm, ScoreLossDetailForm


# -------------------------- 1. 基础视图（保持不变） --------------------------
@login_required
def score_list(request):
    """成绩列表视图函数（支持管理员和普通用户）- 修正版：按用户配置的考试科目统计"""
    # 初始化空的查询集和分页
    empty_records = ExamRecord.objects.none()
    empty_paginator = Paginator(empty_records, 15)

    # 先获取所有科目和考试，用于筛选下拉框
    all_subjects = Subject.objects.all()
    all_exams = Exam.objects.all()

    context = {
        'records_page': empty_paginator.page(1),
        'subjects': all_subjects,  # 使用所有科目，不随筛选变化
        'exams': all_exams,  # 使用所有考试，不随筛选变化
        'total_records': 0,
        'avg_score': 0.0,
        'max_score': 0.0,
        'min_score': 0.0,
        'subject_stats': [],
        'current_filters': {
            'subject': request.GET.get('subject'),
            'exam': request.GET.get('exam'),
            'date_from': request.GET.get('date_from'),
            'date_to': request.GET.get('date_to'),
            'sort_by': request.GET.get('sort_by', '-exam__exam_date'),
        }
    }

    try:
        # 检查用户类型
        if request.user.is_staff or request.user.is_superuser:
            # 管理员：查看所有成绩
            exam_records = ExamRecord.objects.all().select_related('exam', 'subject', 'student')
        else:
            # 普通用户：只能查看自己的成绩
            if hasattr(request.user, 'student'):
                student = request.user.student
                exam_records = ExamRecord.objects.filter(student=student).select_related('exam', 'subject')
            else:
                exam_records = ExamRecord.objects.none()
                messages.info(request, "您的账户未关联学生信息，请联系管理员")

        # 保存筛选前的查询集，用于统计
        original_records = exam_records

        # 筛选逻辑
        subject_filter = context['current_filters']['subject']
        if subject_filter and subject_filter != 'all':
            exam_records = exam_records.filter(subject_id=subject_filter)

        exam_filter = context['current_filters']['exam']
        if exam_filter and exam_filter != 'all':
            exam_records = exam_records.filter(exam_id=exam_filter)

        if context['current_filters']['date_from']:
            exam_records = exam_records.filter(exam__exam_date__gte=context['current_filters']['date_from'])
        if context['current_filters']['date_to']:
            exam_records = exam_records.filter(exam__exam_date__lte=context['current_filters']['date_to'])

        # 排序逻辑
        sort_by = context['current_filters']['sort_by']
        allowed_sort_fields = ['exam__exam_date', '-exam__exam_date', 'subject__name', '-subject__name', 'score',
                               '-score']
        if sort_by in allowed_sort_fields:
            exam_records = exam_records.order_by(sort_by)
        else:
            exam_records = exam_records.order_by('-exam__exam_date', 'subject__order')

        # 分页逻辑
        paginator = Paginator(exam_records, 15)
        page = request.GET.get('page')
        try:
            records_page = paginator.page(page)
        except PageNotAnInteger:
            records_page = paginator.page(1)
        except EmptyPage:
            records_page = paginator.page(paginator.num_pages)

        # 更新上下文 - 注意：exams 仍然使用 all_exams，不随筛选变化
        context['records_page'] = records_page
        context['total_records'] = exam_records.count()

        # 安全地计算整体统计信息（基于筛选后的数据）
        if exam_records.exists():
            context['avg_score'] = round(exam_records.aggregate(avg=Avg('score'))['avg'] or 0, 2)
            context['max_score'] = exam_records.aggregate(max=Max('score'))['max'] or 0
            context['min_score'] = exam_records.aggregate(min=Min('score'))['min'] or 0
        else:
            context['avg_score'] = 0.0
            context['max_score'] = 0.0
            context['min_score'] = 0.0

        # ==================== 修正：按用户配置的考试科目统计 ====================
        # 注意：科目统计使用筛选前的数据，这样统计卡片不会随筛选变化
        subject_stats = []

        if request.user.is_staff or request.user.is_superuser:
            # 管理员：显示所有有成绩的科目
            user_subjects = Subject.objects.filter(
                records__in=original_records  # 使用筛选前的数据
            ).distinct().order_by('order')
        else:
            # 普通用户：基于 Student 模型的科目配置
            if hasattr(request.user, 'student'):
                student = request.user.student
                user_subjects = []

                # 根据学生的考试科目配置来获取科目
                if student.has_politics:
                    politics_subject = Subject.objects.filter(name__contains='政治').first()
                    if politics_subject:
                        user_subjects.append(politics_subject)

                if student.has_english and student.english_type != '不考':
                    # 修复：使用学生的英语类型来匹配科目
                    english_subject = Subject.objects.filter(name=student.english_type).first()
                    if english_subject:
                        user_subjects.append(english_subject)
                    else:
                        # 如果找不到精确匹配，尝试模糊匹配
                        english_subject = Subject.objects.filter(name__contains='英语').first()
                        if english_subject:
                            user_subjects.append(english_subject)

                if student.has_math and student.math_type != '不考':
                    # 修复：使用学生的数学类型来匹配科目
                    math_subject = Subject.objects.filter(name=student.math_type).first()
                    if math_subject:
                        user_subjects.append(math_subject)
                    else:
                        # 如果找不到精确匹配，尝试模糊匹配
                        math_subject = Subject.objects.filter(name__contains='数学').first()
                        if math_subject:
                            user_subjects.append(math_subject)

                # 添加专业课一
                if student.professional_subject_name:
                    prof_subject = Subject.objects.filter(name=student.professional_subject_name).first()
                    if prof_subject:
                        user_subjects.append(prof_subject)

                # 添加专业课二（如果配置了）
                if student.has_professional_2 and student.professional_subject_2_name:
                    prof2_subject = Subject.objects.filter(name=student.professional_subject_2_name).first()
                    if prof2_subject:
                        user_subjects.append(prof2_subject)
            else:
                user_subjects = []

        # 为每个配置的科目生成统计信息（基于筛选前的数据）
        for subject in user_subjects:
            # 该科目的所有成绩记录（使用筛选前的数据）
            subject_records = original_records.filter(subject=subject)
            record_count = subject_records.count()

            if record_count > 0:
                # 有成绩：计算统计信息
                subject_avg = round(subject_records.aggregate(avg=Avg('score'))['avg'] or 0, 2)
                subject_max = subject_records.aggregate(max=Max('score'))['max'] or 0
                subject_min = subject_records.aggregate(min=Min('score'))['min'] or 0

                # 修复：确保使用科目的实际满分值
                actual_full_score = subject.full_score

                # 计算掌握程度（平均分占满分的百分比）
                mastery_rate = round((subject_avg / actual_full_score) * 100, 1) if actual_full_score > 0 else 0

                # 确定掌握程度等级
                if mastery_rate >= 80:
                    mastery_level = '优秀'
                    mastery_color = 'success'
                elif mastery_rate >= 70:
                    mastery_level = '良好'
                    mastery_color = 'info'
                elif mastery_rate >= 60:
                    mastery_level = '及格'
                    mastery_color = 'warning'
                else:
                    mastery_level = '需努力'
                    mastery_color = 'danger'

                has_records = True

                # 调试信息（生产环境可删除）
                print(
                    f"DEBUG - 科目: {subject.name}, 满分: {actual_full_score}, 平均分: {subject_avg}, 掌握率: {mastery_rate}%")
            else:
                # 无成绩：显示默认值
                subject_avg = 0
                subject_max = 0
                subject_min = 0
                mastery_rate = 0
                mastery_level = '暂无成绩'
                mastery_color = 'secondary'
                has_records = False

            subject_stats.append({
                'subject': subject,
                'record_count': record_count,
                'avg_score': subject_avg,
                'max_score': subject_max,
                'min_score': subject_min,
                'full_score': subject.full_score,  # 传递实际满分到模板
                'mastery_rate': mastery_rate,
                'mastery_level': mastery_level,
                'mastery_color': mastery_color,
                'color': subject.color,
                'has_records': has_records,
            })

        context['subject_stats'] = subject_stats
        context['is_admin'] = request.user.is_staff or request.user.is_superuser

    except Exception as e:
        messages.error(request, f"加载成绩列表失败：{str(e)}")
        context['records_page'] = empty_paginator.page(1)

    return render(request, 'score/score_list.html', context)


@login_required
def score_add(request):
    """添加成绩视图函数 - 统一界面设计"""
    try:
        # 检查用户类型
        if request.user.is_staff or request.user.is_superuser:
            # 管理员：需要先选择学生，然后界面与普通用户相同
            if request.method == 'POST':
                # 检查是否选择了学生
                student_id = request.POST.get('student_id')
                if student_id:
                    # 如果选择了学生，创建表单
                    selected_student = get_object_or_404(Student, id=student_id)
                    form = ExamRecordForm(request.POST, student=selected_student)

                    if form.is_valid():
                        exam_record = form.save(commit=False)
                        exam_record.student = selected_student
                        exam_record.save()

                        # 处理失分明细
                        loss_details_count = int(request.POST.get('loss_details_count', 0))
                        for i in range(loss_details_count):
                            loss_type = request.POST.get(f'loss_details[{i}].loss_type')
                            points = request.POST.get(f'loss_details[{i}].points')
                            question_number = request.POST.get(f'loss_details[{i}].question_number')
                            knowledge_point = request.POST.get(f'loss_details[{i}].knowledge_point')
                            description = request.POST.get(f'loss_details[{i}].description')

                            if loss_type and points:
                                ScoreLossDetail.objects.create(
                                    exam_record=exam_record,
                                    loss_type=loss_type,
                                    points=points,
                                    question_number=question_number or '',
                                    custom_knowledge_point=knowledge_point or '',
                                    description=description or ''
                                )

                        messages.success(request, f"成功为 {selected_student.name} 添加成绩")
                        return redirect('score:score_list')  # 重定向到成绩列表
                    else:
                        # 表单验证失败，重新显示表单
                        context = {
                            'form': form,
                            'subjects': Subject.objects.all(),
                            'title': f'为 {selected_student.name} 添加成绩',
                            'is_admin': True,
                            'selected_student': selected_student
                        }
                else:
                    # 如果没有选择学生，显示错误
                    messages.error(request, "请先选择学生")
                    return redirect('score:score_add')
            else:
                # GET请求：显示学生选择页面或成绩表单
                student_id = request.GET.get('student_id')
                if student_id:
                    # 如果已经选择了学生，显示成绩表单
                    selected_student = get_object_or_404(Student, id=student_id)
                    form = ExamRecordForm(student=selected_student)

                    # 关键修复：确保新字段有合理的默认值
                    # 这些默认值已经在表单的 __init__ 方法中设置

                    context = {
                        'form': form,
                        'subjects': Subject.objects.all(),
                        'title': f'为 {selected_student.name} 添加成绩',
                        'is_admin': True,
                        'selected_student': selected_student
                    }
                else:
                    # 显示学生选择页面
                    students = Student.objects.all()
                    context = {
                        'students': students,
                        'title': '选择学生',
                        'is_admin': True,
                        'show_student_selection': True
                    }

        else:
            # 普通用户：只能给自己添加成绩
            student = request.user.student

            if request.method == 'POST':
                form = ExamRecordForm(request.POST, student=student)
                if form.is_valid():
                    exam_record = form.save(commit=False)
                    exam_record.student = student
                    exam_record.save()

                    # 处理失分明细
                    loss_details_count = int(request.POST.get('loss_details_count', 0))
                    for i in range(loss_details_count):
                        loss_type = request.POST.get(f'loss_details[{i}].loss_type')
                        points = request.POST.get(f'loss_details[{i}].points')
                        question_number = request.POST.get(f'loss_details[{i}].question_number')
                        knowledge_point = request.POST.get(f'loss_details[{i}].knowledge_point')
                        description = request.POST.get(f'loss_details[{i}].description')

                        if loss_type and points:
                            ScoreLossDetail.objects.create(
                                exam_record=exam_record,
                                loss_type=loss_type,
                                points=points,
                                question_number=question_number or '',
                                custom_knowledge_point=knowledge_point or '',
                                description=description or ''
                            )

                    messages.success(request, f"成功添加 {exam_record.subject.name} 成绩: {exam_record.score}分")
                    return redirect('score:score_list')  # 重定向到成绩列表
                else:
                    # 表单验证失败，重新显示表单
                    context = {
                        'form': form,
                        'subjects': Subject.objects.all(),
                        'title': '添加成绩',
                        'is_admin': False,
                        'student': student
                    }
            else:
                form = ExamRecordForm(student=student)

                # 关键修复：确保新字段有合理的默认值
                # 这些默认值已经在表单的 __init__ 方法中设置

                context = {
                    'form': form,
                    'subjects': Subject.objects.all(),
                    'title': '添加成绩',
                    'is_admin': False,
                    'student': student
                }

        return render(request, 'score/score_form.html', context)

    except Exception as e:
        messages.error(request, f"添加成绩时出错: {str(e)}")
        return redirect('score:score_list')


@login_required
def score_add_multiple(request):
    """批量添加成绩视图"""
    try:
        student = request.user.student
        all_subjects = list(Subject.objects.all())

        # 自定义表单集
        class ExamRecordFormSet(BaseFormSet):
            def __init__(self, *args, **kwargs):
                self.student = kwargs.pop('student', None)
                self.initial_subjects = kwargs.pop('initial_subjects', [])
                super().__init__(*args, **kwargs)

            def _construct_form(self, i, **kwargs):
                kwargs['student'] = self.student
                kwargs['initial_subjects'] = self.initial_subjects
                form = super()._construct_form(i, **kwargs)
                return form

        ExamRecordFormSet = formset_factory(ExamRecordForm, formset=ExamRecordFormSet, extra=3)

        # POST提交
        if request.method == 'POST':
            formset = ExamRecordFormSet(request.POST, student=student, initial_subjects=all_subjects)
            if formset.is_valid():
                saved_count = 0
                for form in formset:
                    if form.has_changed():
                        exam_record = form.save(commit=False)
                        exam_record.student = student
                        exam_record.save()
                        saved_count += 1
                if saved_count > 0:
                    messages.success(request, f"成功添加 {saved_count} 条成绩记录")
                return redirect('score:score_list')
            else:
                messages.error(request, "请更正下面的错误")
        else:
            formset = ExamRecordFormSet(student=student, initial_subjects=all_subjects)

        context = {'formset': formset, 'title': '批量添加成绩'}
        return render(request, 'score/score_form_multiple.html', context)

    except Exception as e:
        messages.error(request, f"批量添加成绩时出错: {str(e)}")
        return redirect('score:score_list')


@login_required
def get_exam_subjects(request):
    """AJAX获取考试科目"""
    try:
        exam_id = request.GET.get('exam_id')
        if exam_id:
            exam = get_object_or_404(Exam, id=exam_id)
            subjects = Subject.objects.filter(records__exam=exam).distinct().values('id', 'name')
            return JsonResponse(list(subjects), safe=False)
        return JsonResponse([], safe=False)
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=400)


@login_required
def score_detail(request, pk):
    """成绩详情视图"""
    exam_record = get_object_or_404(ExamRecord, pk=pk)
    # 权限控制
    if exam_record.student.user != request.user:
        return HttpResponseForbidden("你没有权限查看这条成绩记录")

    # 失分明细
    loss_details = ScoreLossDetail.objects.filter(exam_record=exam_record).order_by("-created_at")
    total_loss = sum(detail.points for detail in loss_details)
    score_rate = (exam_record.score / exam_record.subject.full_score) * 100 if exam_record.subject.full_score != 0 else 0

    context = {
        "exam_record": exam_record,
        "loss_details": loss_details,
        "total_loss": total_loss,
        "score_rate": round(score_rate, 1),
        "full_score": exam_record.subject.full_score,
        "back_url": request.META.get("HTTP_REFERER", "score:score_list"),
    }
    return render(request, "score/score_detail.html", context)


@login_required
def score_edit(request, pk):
    """编辑成绩视图 - 修复字段初始化"""
    exam_record = get_object_or_404(ExamRecord, pk=pk)

    # 权限控制
    if request.user != exam_record.student.user and not request.user.is_staff:
        messages.error(request, "你没有权限编辑这条成绩记录")
        return HttpResponseForbidden("无编辑权限")

    if request.method == "POST":
        form = ExamRecordForm(request.POST, instance=exam_record, student=exam_record.student)
        if form.is_valid():
            updated_record = form.save(commit=False)

            # 校验失分明细总分
            loss_details = ScoreLossDetail.objects.filter(exam_record=updated_record)
            if loss_details.exists():
                total_loss = loss_details.aggregate(total=Sum("points"))["total"] or 0
                max_allowed_loss = updated_record.subject.full_score - updated_record.score
                if total_loss > max_allowed_loss:
                    messages.error(request, f"失分明细总分({total_loss}分)超过允许范围（最大{max_allowed_loss}分）")
                    return redirect("score:score_edit", pk=pk)

            # 保存
            updated_record.save()
            messages.success(request, f"「{updated_record.exam.name} - {updated_record.subject.name}」成绩修改成功！")

            # 修复权限问题：根据用户类型重定向到不同页面
            if request.user.is_staff or request.user.is_superuser:
                return redirect('score:score_list')  # 管理员返回列表
            else:
                return redirect("score:score_detail", pk=updated_record.pk)  # 普通用户返回详情
        else:
            messages.error(request, "表单填写有误，请检查后重新提交")
    else:
        # GET请求：正确初始化表单数据
        form = ExamRecordForm(instance=exam_record, student=exam_record.student)

        # 关键修复：手动设置所有字段的初始值
        if exam_record.exam:
            # 设置考试相关字段的初始值
            form.fields['exam'].initial = exam_record.exam.id
            form.fields['custom_exam_base_name'].initial = exam_record.exam.base_name
            form.fields['custom_exam_sequence'].initial = exam_record.exam.sequence_number
            form.fields['exam_date'].initial = exam_record.exam.exam_date  # 日期保持可编辑

        # 设置科目字段的初始值
        form.fields['subject'].initial = exam_record.subject.name

        # 设置基础字段的初始值
        form.fields['score'].initial = exam_record.score
        form.fields['exam_duration'].initial = exam_record.exam_duration
        form.fields['exam_status'].initial = exam_record.exam_status

        # 关键修复：设置新添加字段的初始值
        form.fields['target_score'].initial = exam_record.target_score
        form.fields['question_completion'].initial = exam_record.question_completion
        form.fields['difficulty_level'].initial = exam_record.difficulty_level
        form.fields['time_management'].initial = exam_record.time_management

    # 构建与 score_add 相同的上下文结构
    context = {
        "form": form,
        "exam_record": exam_record,
        "title": f"编辑「{exam_record.exam.name} - {exam_record.subject.name}」成绩",
        "is_edit": True,
        "is_admin": request.user.is_staff or request.user.is_superuser,
        "student": exam_record.student,
        "subjects": Subject.objects.all(),
        "show_student_selection": False,
    }

    return render(request, "score/score_form.html", context)


@login_required
def score_delete(request, pk):
    """删除成绩视图"""
    record = get_object_or_404(ExamRecord, pk=pk)

    # 权限检查：允许管理员或成绩记录的所有者删除
    if not (request.user.is_staff or request.user.is_superuser or record.student.user == request.user):
        return HttpResponseForbidden("你没有权限删除这条成绩记录")

    if request.method == 'POST':
        record.delete()
        messages.success(request, "成绩记录已成功删除")
        return redirect('score:score_list')
    elif request.method == 'GET':
        return HttpResponseNotAllowed(['POST'], "仅允许POST请求删除记录")
    return HttpResponseNotAllowed(['POST'])


@login_required
def loss_detail_delete(request, pk):
    """删除失分明细视图"""
    loss_detail = get_object_or_404(ScoreLossDetail, pk=pk)
    if loss_detail.exam_record.student.user != request.user:
        return HttpResponseForbidden("你没有权限删除这条失分明细")

    if request.method == 'POST':
        exam_record_id = loss_detail.exam_record.id
        loss_detail.delete()
        messages.success(request, "失分明细已成功删除")
        return redirect('score:score_detail',pk=exam_record_id)
    elif request.method == 'GET':
        return HttpResponseNotAllowed(['POST'], "仅允许POST请求删除记录")
    return HttpResponseNotAllowed(['POST'])


@login_required
def loss_detail_add(request, record_id):
    """添加失分明细视图"""
    exam_record = get_object_or_404(ExamRecord, pk=record_id)
    # 权限控制：本人或管理员
    if exam_record.student.user != request.user and not request.user.is_staff:
        messages.error(request, "你没有权限为这条成绩添加失分明细")
        return HttpResponseForbidden("无添加权限")

    # 计算最大允许失分
    max_allowed_loss = exam_record.subject.full_score - exam_record.score
    if max_allowed_loss <= 0:
        messages.error(request, f"当前成绩已为满分（{exam_record.subject.full_score}分），无需添加失分明细")
        return redirect("score:score_detail", pk=exam_record.pk)

    # GET请求：初始化表单
    if request.method == "GET":
        form = ScoreLossDetailForm(
            initial={"question_number": ""},
            exam_record=exam_record  # 只传递 exam_record
        )
        context = {
            "form": form,
            "exam_record": exam_record,
            "max_allowed_loss": round(max_allowed_loss, 1),
            "title": f"添加「{exam_record.exam.name}-{exam_record.subject.name}」失分明细",
            "back_url": reverse("score:score_detail", args=[exam_record.pk])
        }
        return render(request, "score/loss_detail_form.html", context)

    # POST请求：提交表单
    elif request.method == "POST":
        form = ScoreLossDetailForm(
            request.POST,
            exam_record=exam_record  # 只传递 exam_record
        )
        if form.is_valid():
            loss_detail = form.save(commit=False)
            loss_detail.exam_record = exam_record
            loss_detail.is_understand = False
            loss_detail.save()
            messages.success(request, f"成功添加失分明细：{loss_detail.get_loss_type_display()}（-{loss_detail.points}分）")
            return redirect("score:score_detail", pk=exam_record.pk)
        else:
            messages.error(request, "表单填写有误，请检查后重新提交")
            context = {
                "form": form,
                "exam_record": exam_record,
                "max_allowed_loss": round(max_allowed_loss, 1),
                "title": f"添加「{exam_record.exam.name}-{exam_record.subject.name}」失分明细",
                "back_url": reverse("score:score_detail", args=[exam_record.pk])
            }
            return render(request, "score/loss_detail_form.html", context)

    # 禁止其他请求方法
    else:
        return HttpResponseNotAllowed(["GET", "POST"], "仅允许GET/POST请求")


# -------------------------- 2. 修复失分明细编辑相关逻辑 --------------------------


def can_edit_loss_detail(user, loss_detail):
    """
    权限检查函数：
    - 接收一个已存在的 loss_detail 对象
    - 判断用户是否为管理员或失分明细的所有者
    """
    return user.is_staff or loss_detail.exam_record.student.user == user

from django.contrib.auth.decorators import user_passes_test, login_required



@login_required
def loss_detail_edit(request, pk):
    """失分明细编辑视图"""
    # 获取失分明细记录
    loss_detail = get_object_or_404(ScoreLossDetail, pk=pk)
    exam_record = loss_detail.exam_record
    student = exam_record.student

    # 权限验证：仅允许管理员或成绩所有者编辑
    if not (request.user.is_superuser or request.user == student.user):
        return HttpResponseForbidden("无编辑权限：仅允许管理员或成绩所有者操作")

    if request.method == 'POST':
        # 🔴 重要：传递exam_record参数给表单
        form = ScoreLossDetailForm(
            request.POST,
            instance=loss_detail,
            exam_record=exam_record  # 确保表单能获取考试记录信息
        )
        if form.is_valid():
            # 保存表单（已处理自定义知识点逻辑）
            form.save()
            # 重定向到成绩详情页
            return redirect(reverse('score:score_detail', args=[exam_record.pk]))
    else:
        #  GET请求：初始化表单（传递exam_record确保知识点过滤正确）
        form = ScoreLossDetailForm(
            instance=loss_detail,
            exam_record=exam_record
        )

    # 渲染编辑页面
    context = {
        'form': form,
        'loss_detail': loss_detail,
        'exam_record': exam_record,
        'page_title': f"编辑「{exam_record.exam.name}-{exam_record.subject.name}」失分明细"
    }
    return render(request, 'score/loss_detail_form.html', context)


@login_required
def loss_detail_create(request, exam_record_id):
    """失分明细创建视图（补充完整逻辑）"""
    exam_record = get_object_or_404(ExamRecord, pk=exam_record_id)
    student = exam_record.student

    # 权限验证
    if not (request.user.is_superuser or request.user == student.user):
        return HttpResponseForbidden("无创建权限")

    if request.method == 'POST':
        form = ScoreLossDetailForm(
            request.POST,
            exam_record=exam_record  # 传递考试记录
        )
        if form.is_valid():
            form.save()
            return redirect(reverse('score:score_detail', args=[exam_record.pk]))
    else:
        form = ScoreLossDetailForm(exam_record=exam_record)

    context = {
        'form': form,
        'exam_record': exam_record,
        'page_title': f"添加「{exam_record.exam.name}-{exam_record.subject.name}」失分明细"
    }
    return render(request, 'score/loss_detail_form.html', context)